package game.editer.view;

import game.editer.ui.NumberInput;
import game.editer.ui.KeyInput.KeyDisplay;
import hx.display.InputLabel;
import hx.events.Event;
import game.editer.config.AtlasXmlDataConfig;
import hx.display.VBox;
import hx.events.Keyboard;
import hx.events.KeyboardEvent;
import game.utils.KeybarodTools;
import hx.events.MouseEvent;
import game.editer.ui.Button;
import haxe.io.Path;
import sys.io.File;
import game.editer.ui.IAttributeInput;
import game.editer.ui.InputCreater;
import hx.display.HBox;
import hx.display.Quad;
import hx.layout.AnchorLayout;
import hx.display.Box;
import game.worlds.GameEffect;
import hx.layout.AnchorLayoutData;
import hx.display.Scroll;

/**
 * 精灵图偏移编辑器
 */
@:access(game.worlds.GameEffect)
class AtlasOffestEditerView extends AlertView {
	override function onInit() {
		super.onInit();
	}

	public var gameEffect:GameEffect;

	public var data:Dynamic = {
		x: 0.,
		y: 0.,
		x2: 0.,
		y2: 0.,
	};

	/**
	 * 属性编辑器
	 */
	public var attribute:AttrEditer;

	/**
	 * 当前编辑的XML数据
	 */
	public var currentXmlData:Xml;

	/**
	 * 当前编辑的XML帧数据
	 */
	public var atlasFrameXmlData:Array<Xml> = [];

	public var frameInput:NumberInput;

	public function edit(id:String):Void {
		var scroll = new Scroll();
		body.addChild(scroll);
		scroll.layoutData = new AnchorLayoutData(3, 248, 40, 3);
		scroll.scrollXEnable = scroll.scrollYEnable = false;

		// var box = new Box();
		// scroll.addChild(box);
		// box.layoutData = AnchorLayoutData.center();

		var quad = new Quad(1, 1, 0xff0000);
		scroll.addChild(quad);
		quad.layoutData = new AnchorLayoutData(null, 0, null, 0, null, 0);

		var quad = new Quad(1, 1, 0xff0000);
		scroll.addChild(quad);
		quad.layoutData = new AnchorLayoutData(0, null, 0, null, 0, null);

		gameEffect = new GameEffect(EditerStage.world.role, id);
		scroll.addChild(gameEffect);
		// gameEffect.x = gameEffect.y = 300;
		gameEffect.liveTime = 0;
		gameEffect.width = gameEffect.height = 1;
		gameEffect.layoutData = AnchorLayoutData.center();
		this.updateEnabled = true;

		// 坐标编辑值

		attribute = new AttrEditer();
		attribute.width = 245;
		attribute.layoutData = new AnchorLayoutData(36, 0, 0);
		this.addChild(attribute);
		attribute.addEventListener(Event.CHANGE, onAttrChange);

		// 全局坐标读取
		var xmlPath = Path.join([EditerStage.projectImagesPath, id + ".xml"]);
		currentXmlData = Xml.parse(File.getContent(xmlPath));
		for (xml in currentXmlData.firstElement().elements()) {
			atlasFrameXmlData.push(xml);
		}
		if (currentXmlData.firstElement().exists("px")) {
			data.x2 = Std.parseInt(currentXmlData.firstElement().get("px"));
			data.y2 = Std.parseInt(currentXmlData.firstElement().get("py"));
		}
		var pos = EditerStage.roleAssets.data.getOffestPoint(id);
		data.x = pos.x;
		data.y = pos.y;
		updateStyle();

		frameInput = new NumberInput("当前帧", "frame", (input) -> {
			this.gameEffect.currentFrame = cast(input.value, Int) - 1;
		});
		frameInput.layoutData = AnchorLayoutData.bottomLeft(5, 5);
		this.addChild(frameInput);

		var button = new Button();
		button.text = "确定";
		button.width = 100;
		this.addChild(button);
		button.layoutData = AnchorLayoutData.bottomCenter(5, 0);
		button.addEventListener(MouseEvent.CLICK, (e:MouseEvent) -> {
			currentXmlData.firstElement().set("px", Std.string(data.x2));
			currentXmlData.firstElement().set("py", Std.string(data.y2));
			// 保存xml数据
			File.saveContent(xmlPath, currentXmlData.toString());
			Reflect.setProperty(EditerStage.roleAssets.data.offestConfig, id, {x: data.x, y: data.y});
			EditerStage.world.role.updateAllMovieClipActionData();
			this.remove();
		});

		this.updateGameEffectData();
	}

	private function onAttrChange(e:Event):Void {
		var xmlData:XmlData = this.attribute.editData;
		data.x2 = xmlData.globalX;
		data.y2 = xmlData.globalY;
		data.x = xmlData.projectX;
		data.y = xmlData.projectY;
		if (gameEffect.__movieClip.data.frameRect != null) {
			gameEffect.__movieClip.data.frameRect.x = xmlData.frameX;
			gameEffect.__movieClip.data.frameRect.y = xmlData.frameY;
			gameEffect.__movieClip.data.frameRect.width = xmlData.frameWidth;
			gameEffect.__movieClip.data.frameRect.height = xmlData.frameHeight;
		}
		trace("data=", data);
		updateStyle();
	}

	public function updateStyle():Void {
		if (data.x != 0 || data.y != 0) {
			gameEffect.originX = data.x;
			gameEffect.originY = data.y;
		} else {
			gameEffect.originX = data.x2;
			gameEffect.originY = data.y2;
		}
	}

	override function onAddToStage() {
		super.onAddToStage();
		this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
	}

	override function onRemoveToStage() {
		super.onRemoveToStage();
		this.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
	}

	private function onKeyDown(e:KeyboardEvent) {
		if (stage.focus is InputLabel) {
			return;
		}
		if (stage.focus is KeyDisplay) {
			return;
		}
		switch (e.keyCode) {
			case Keyboard.EQUAL:
				// 下一帧
				gameEffect.nextFrame();
				this.frameInput.value = gameEffect.currentFrame + 1;
				this.updateGameEffectData();
			case Keyboard.MINUS:
				// 上一帧
				gameEffect.prevFrame();
				this.frameInput.value = gameEffect.currentFrame + 1;
				this.updateGameEffectData();
		}
	}

	public function updateGameEffectData():Void {
		var data = new XmlData(atlasFrameXmlData[gameEffect.currentFrame]);
		var pos = EditerStage.roleAssets.data.getOffestPoint(gameEffect.id);
		data.projectX = pos.x;
		data.projectY = pos.y;
		attribute.bindEditData("属性", data, AtlasXmlDataConfig.ATTRIBUTES);
	}

	override function onUpdate(dt:Float) {
		super.onUpdate(dt);
		if (gameEffect != null) {
			// gameEffect.onUpdate(dt);
		}
	}
}

class XmlData {
	public var xml:Xml;

	public function new(xml:Xml):Void {
		this.xml = xml;
	}

	public var globalX:Float = 0;

	public var globalY:Float = 0;

	/**
	 * 项目偏移值X
	 */
	public var projectX:Float = 0;

	/**
	 * 项目偏移值Y
	 */
	public var projectY:Float = 0;

	public var frameX(get, set):Float;

	private function get_frameX():Float {
		if (!xml.exists("frameX")) {
			return 0;
		}
		return Std.parseInt(xml.get("frameX"));
	}

	private function set_frameX(value:Float):Float {
		xml.set("frameX", Std.string(value));
		return value;
	}

	public var frameY(get, set):Float;

	private function get_frameY():Float {
		if (!xml.exists("frameY")) {
			return 0;
		}
		return Std.parseInt(xml.get("frameY"));
	}

	private function set_frameY(value:Float):Float {
		xml.set("frameY", Std.string(value));
		return value;
	}

	public var frameWidth(get, set):Float;

	private function get_frameWidth():Float {
		if (!xml.exists("frameWidth")) {
			return 0;
		}
		return Std.parseInt(xml.get("frameWidth"));
	}

	private function set_frameWidth(value:Float):Float {
		xml.set("frameWidth", Std.string(value));
		return value;
	}

	public var frameHeight(get, set):Float;

	private function get_frameHeight():Float {
		if (!xml.exists("frameHeight")) {
			return 0;
		}
		return Std.parseInt(xml.get("frameHeight"));
	}

	private function set_frameHeight(value:Float):Float {
		xml.set("frameHeight", Std.string(value));
		return value;
	}
}
